#include "historydatawidget.h"
#include "sqlitemanage.h"

HistoryDataWidget::HistoryDataWidget(QWidget *parent) : QWidget(parent),
    m_dataModel(nullptr),
    m_chart(nullptr),
    m_chartView(nullptr),
    m_pSqliteManage(nullptr),
    m_isQuerying(false)
{
    m_pSqliteManage = new SqliteManage;
    // 连接数据库
    if (!m_pSqliteManage->openDatabase("C:/Users/shafl/Desktop/FrameWork/test.db")) {
        qCritical() << "数据库连接失败：" << m_pSqliteManage->lastError();
    }
    m_pLog = LogClass::getInstance();
    // 初始化数据模型
    setupModels();

    // 初始化UI
    setupUI();

    // 加载设备列表（此时 m_deviceComboBox 已初始化）
    loadDeviceList();
}

HistoryDataWidget::~HistoryDataWidget()
{
    delete m_tableView;  // 先释放表格视图
    delete m_dataModel;  // 再释放数据模型
    delete m_chartView;  // 释放图表视图（会自动删除 m_chart）
    delete m_pSqliteManage;  // 最后释放数据库管理器
}

void HistoryDataWidget::setUserName(QString &name)
{
    this->username = name;
}

void HistoryDataWidget::setupUI()
{
    // 整体布局使用 QVBoxLayout
    QVBoxLayout *mainLayout = new QVBoxLayout(this);
    mainLayout->setContentsMargins(10, 10, 10, 10);
    mainLayout->setSpacing(10);

    // 查询区域
    QGroupBox *queryGroupBox = new QGroupBox("查询条件", this);
    QGridLayout *queryLayout = new QGridLayout(queryGroupBox);
    queryLayout->setContentsMargins(10, 10, 10, 10);
    queryLayout->setSpacing(8);

    m_refreshButton = new QPushButton("刷新", queryGroupBox);
    m_refreshButton->setIcon(QIcon(":/icons/refresh.png"));  // 可添加刷新图标
    m_refreshButton->setMinimumWidth(80);

    // 设备选择
    QLabel *deviceLabel = new QLabel("设备:", queryGroupBox);
    m_deviceComboBox = new QComboBox(queryGroupBox);
    m_deviceComboBox->setMinimumWidth(120);

    // 时间选择
    QLabel *startLabel = new QLabel("开始时间:", queryGroupBox);
    m_startDateTimeEdit = new QDateTimeEdit(QDateTime::currentDateTime().addDays(-1), queryGroupBox);
    m_startDateTimeEdit->setDisplayFormat("yyyy-MM-dd HH:mm:ss");
    m_startDateTimeEdit->setMinimumWidth(150);

    QLabel *endLabel = new QLabel("结束时间:", queryGroupBox);
    m_endDateTimeEdit = new QDateTimeEdit(QDateTime::currentDateTime(), queryGroupBox);
    m_endDateTimeEdit->setDisplayFormat("yyyy-MM-dd HH:mm:ss");
    m_endDateTimeEdit->setMinimumWidth(150);

    // 查询按钮
    m_queryButton = new QPushButton("查询", queryGroupBox);
    m_queryButton->setMinimumWidth(80);

    // 图表类型选择
    QLabel *chartTypeLabel = new QLabel("图表类型:", queryGroupBox);
    m_chartTypeComboBox = new QComboBox(queryGroupBox);
    m_chartTypeComboBox->addItems({"折线图", "柱状图"});
    m_chartTypeComboBox->setMinimumWidth(100);

    // 布局排列（优化网格位置，避免控件挤压）
    queryLayout->addWidget(deviceLabel, 0, 0, Qt::AlignRight);
    queryLayout->addWidget(m_deviceComboBox, 0, 1);
    queryLayout->addWidget(chartTypeLabel, 0, 2, Qt::AlignRight);
    queryLayout->addWidget(m_chartTypeComboBox, 0, 3);
    queryLayout->addWidget(startLabel, 1, 0, Qt::AlignRight);
    queryLayout->addWidget(m_startDateTimeEdit, 1, 1);
    queryLayout->addWidget(endLabel, 1, 2, Qt::AlignRight);
    queryLayout->addWidget(m_endDateTimeEdit, 1, 3);
    queryLayout->addWidget(m_refreshButton, 0, 4);
    queryLayout->addWidget(m_queryButton, 1, 4);

    // 设置列拉伸策略（关键：让时间控件自适应宽度）
    queryLayout->setColumnStretch(1, 1);
    queryLayout->setColumnStretch(3, 1);

    // 导出按钮区域
    QHBoxLayout *exportLayout = new QHBoxLayout();
    exportLayout->addStretch();
    m_exportCsvButton = new QPushButton("导出CSV", this);
    m_exportExcelButton = new QPushButton("导出Excel", this);
    exportLayout->addWidget(m_exportCsvButton);
    exportLayout->addWidget(m_exportExcelButton);

    // 数据表格（解决不显示问题）
    m_tableView = new QTableView(this);
    m_tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    m_tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
    m_tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); // 列自适应
    m_tableView->verticalHeader()->setVisible(false); // 隐藏行号，节省空间
    m_tableView->setAlternatingRowColors(true); // 隔行变色，增强可读性

    // 图表区域 - 确保正确初始化 QChart 和 QChartView
    m_chart = new QChart();
    m_chartView = new QChartView(m_chart, this);
    m_chartView->setRenderHint(QPainter::Antialiasing);
    m_chartView->setMinimumHeight(300); // 保证图表最小高度

    // 滚动区域（仅表格需要，图表高度足够）
    QScrollArea *tableScrollArea = new QScrollArea(this);
    tableScrollArea->setWidgetResizable(true);
    tableScrollArea->setWidget(m_tableView);
    tableScrollArea->setMinimumHeight(150); // 表格最小高度

    // 分割器（调整占比：表格30%，图表70%）
    QSplitter *splitter = new QSplitter(Qt::Vertical, this);
    splitter->addWidget(tableScrollArea);
    splitter->addWidget(m_chartView);
    splitter->setSizes({300, 700}); // 初始高度比 3:7
    splitter->setHandleWidth(6);

    // 组装整体布局
    mainLayout->addWidget(queryGroupBox);
    mainLayout->addLayout(exportLayout);
    mainLayout->addWidget(splitter, 1); // 让分割器占满剩余空间

    // 关键：设置数据模型到表格（确保 m_dataModel 已在 setupModels() 中初始化）
    if (m_dataModel) {
        m_tableView->setModel(m_dataModel);

        // 初始化表头
        m_dataModel->setHeaderData(0, Qt::Horizontal, "ID");
        m_dataModel->setHeaderData(1, Qt::Horizontal, "设备ID");
        m_dataModel->setHeaderData(2, Qt::Horizontal, "设备名称");
        m_dataModel->setHeaderData(3, Qt::Horizontal, "温度 (°C)");
        m_dataModel->setHeaderData(4, Qt::Horizontal, "湿度 (%)");
        m_dataModel->setHeaderData(5, Qt::Horizontal, "光照 (lux)");
        m_dataModel->setHeaderData(6, Qt::Horizontal, "时间戳");
    } else {
        qCritical() << "Error: m_dataModel is null in setupUI()";
    }

    // 信号连接
    connect(m_queryButton, &QPushButton::clicked, this, &HistoryDataWidget::onQueryButtonClicked);
    connect(m_exportCsvButton, &QPushButton::clicked, this, &HistoryDataWidget::onExportCsvButtonClicked);
    connect(m_exportExcelButton, &QPushButton::clicked, this, &HistoryDataWidget::onExportExcelButtonClicked);
    connect(m_chartTypeComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &HistoryDataWidget::onChartTypeChanged);
    connect(m_refreshButton, &QPushButton::clicked, this, &HistoryDataWidget::onRefreshButtonClicked);
}

void HistoryDataWidget::setupModels()
{
    // 只初始化数据模型，不操作 m_deviceComboBox
    m_dataModel = new QSqlQueryModel(this);
}

void HistoryDataWidget::loadDeviceList()
{
    if (!m_deviceComboBox) {
        qCritical() << "Error: m_deviceComboBox is null in loadDeviceList()";
        return;
    }

    // 保存当前选中的设备ID（刷新后尝试恢复选中状态）
    int currentDeviceId = m_deviceComboBox->currentData().toInt();

    QSqlQuery query;
    if (m_pSqliteManage->getDeviceList(query)) {
        if (!query.isActive()) {
            qCritical() << "Invalid device list query:" << query.lastError().text();
            m_pLog->log(m_pSqliteManage,SYSTEM_LOG,ERR,"历史数据页设备列表加载失败");
            return;
        }

        // 清空并重新加载设备列表
        m_deviceComboBox->clear();
        m_deviceComboBox->addItem("全部设备", -1);  // 默认选项

        bool foundCurrent = false;
        while (query.next()) {
            int id = query.value("device_id").toInt();
            QString name = query.value("name").toString();
            m_deviceComboBox->addItem(name, id);

            // 记录当前设备是否在列表中
            if (id == currentDeviceId) {
                foundCurrent = true;
            }
        }

        // 恢复选中状态（如果设备仍存在）
        if (foundCurrent && currentDeviceId != -1) {
            m_deviceComboBox->setCurrentIndex(m_deviceComboBox->findData(currentDeviceId));
        } else {
            // 设备已被删除，默认选中"全部设备"
            m_deviceComboBox->setCurrentIndex(0);
        }
    } else {
        qCritical() << "获取设备列表失败";
    }
}

void HistoryDataWidget::onRefreshButtonClicked()
{
    // 显示刷新状态
    m_refreshButton->setEnabled(false);
    m_refreshButton->setText("刷新中...");
    m_queryButton->setEnabled(false);  // 刷新期间禁用查询按钮

    // 1. 先刷新设备列表（QComboBox）
    loadDeviceList();  // 重新加载设备列表，覆盖现有选项

    // 2. 保存当前查询参数（刷新后保持用户选择的设备和时间范围）
    int deviceId = m_deviceComboBox->currentData().toInt();
    QDateTime startTime = m_startDateTimeEdit->dateTime();
    QDateTime endTime = m_endDateTimeEdit->dateTime();

    // 3. 重新执行查询（复用查询逻辑）
    QFuture<void> future = QtConcurrent::run([this, deviceId, startTime, endTime]() {
        QSqlQuery query = m_pSqliteManage->querySensorData(deviceId, startTime, endTime);

        // 在主线程更新UI
        QMetaObject::invokeMethod(this, [this, query]() {
            // 更新表格数据
            m_dataModel->setQuery(query);
            m_dataModel->setHeaderData(0, Qt::Horizontal, "ID");
            m_dataModel->setHeaderData(1, Qt::Horizontal, "设备ID");
            m_dataModel->setHeaderData(2, Qt::Horizontal, "设备名称");
            m_dataModel->setHeaderData(3, Qt::Horizontal, "温度 (°C)");
            m_dataModel->setHeaderData(4, Qt::Horizontal, "湿度 (%)");
            m_dataModel->setHeaderData(5, Qt::Horizontal, "光照 (lux)");
            m_dataModel->setHeaderData(6, Qt::Horizontal, "时间戳");

            // 更新图表
            updateChart();

            // 恢复按钮状态
            m_refreshButton->setEnabled(true);
            m_refreshButton->setText("刷新");
            m_queryButton->setEnabled(true);
        }, Qt::QueuedConnection);
    });
}

void HistoryDataWidget::onQueryButtonClicked()
{
    if (m_isQuerying) {
            QMessageBox::information(this, "查询中", "正在执行上次查询，请稍候...");
            return;
        }

        int deviceId = m_deviceComboBox->currentData().toInt();
        QDateTime startTime = m_startDateTimeEdit->dateTime();
        QDateTime endTime = m_endDateTimeEdit->dateTime();

        if (startTime >= endTime) {
            QMessageBox::warning(this, "时间错误", "开始时间必须早于结束时间!");
            return;
        }

        // 检查是否重复查询
        if (isDuplicateQuery(deviceId, startTime, endTime)) {
            return;
        }

        m_isQuerying = true;
        m_queryButton->setEnabled(false);
        m_queryButton->setText("查询中...");

        // 使用QtConcurrent在后台执行查询
        QFuture<void> future = QtConcurrent::run([this, deviceId, startTime, endTime]() {
        QSqlQuery query = m_pSqliteManage->querySensorData(deviceId, startTime, endTime);

        // 在主线程更新UI
        QMetaObject::invokeMethod(this, [this, query]() {
            m_dataModel->setQuery(query);
            m_dataModel->setHeaderData(0, Qt::Horizontal, "ID");
            m_dataModel->setHeaderData(1, Qt::Horizontal, "设备ID");
            m_dataModel->setHeaderData(2, Qt::Horizontal, "设备名称");
            m_dataModel->setHeaderData(3, Qt::Horizontal, "温度 (°C)");
            m_dataModel->setHeaderData(4, Qt::Horizontal, "湿度 (%)");
            m_dataModel->setHeaderData(5, Qt::Horizontal, "光照 (lux)");
            m_dataModel->setHeaderData(6, Qt::Horizontal, "时间戳");

            updateChart();

            m_isQuerying = false;
            m_queryButton->setEnabled(true);
            m_queryButton->setText("查询");
        }, Qt::QueuedConnection);
    });
}

void HistoryDataWidget::updateChart()
{
    m_chart->removeAllSeries();
    foreach (QAbstractAxis *axis, m_chart->axes()) {
        m_chart->removeAxis(axis);
    }

    if (m_dataModel->rowCount() == 0) {
        return;
    }

    bool isLineChart = m_chartTypeComboBox->currentText() == "折线图";

    // 准备数据
    QList<QDateTime> timestamps;
    QList<double> temperatures;
    QList<double> humidities;
    QList<double> lights;

    for (int i = 0; i < m_dataModel->rowCount(); i++) {
        timestamps.append(QDateTime::fromString(m_dataModel->data(m_dataModel->index(i, 6)).toString(), "yyyy-MM-ddTHH:mm:ss.zzz"));
        temperatures.append(m_dataModel->data(m_dataModel->index(i, 3)).toDouble());
        humidities.append(m_dataModel->data(m_dataModel->index(i, 4)).toDouble());
        lights.append(m_dataModel->data(m_dataModel->index(i, 5)).toDouble());
    }

    // 创建坐标轴
    QDateTimeAxis *axisX = new QDateTimeAxis;
    axisX->setFormat("MM-dd HH:mm");
    axisX->setTitleText("时间");

    QValueAxis *axisY = new QValueAxis;
    axisY->setTitleText("数值");

    m_chart->addAxis(axisX, Qt::AlignBottom);
    m_chart->addAxis(axisY, Qt::AlignLeft);
    m_chart->setTheme(QChart::ChartThemeLight);
    m_chart->setAnimationOptions(QChart::AllAnimations);

    if (isLineChart) {
        // 创建折线图
        QLineSeries *tempSeries = new QLineSeries();
        QLineSeries *humiditySeries = new QLineSeries();
        QLineSeries *lightSeries = new QLineSeries();

        tempSeries->setName("温度 (°C)");
        humiditySeries->setName("湿度 (%)");
        lightSeries->setName("光照 (lux)");

        for (int i = 0; i < timestamps.size(); i++) {
            tempSeries->append(timestamps[i].toMSecsSinceEpoch(), temperatures[i]);
            humiditySeries->append(timestamps[i].toMSecsSinceEpoch(), humidities[i]);
            lightSeries->append(timestamps[i].toMSecsSinceEpoch(), lights[i]);
            qDebug()<<temperatures[i]<<humidities[i]<<lights[i];//可以得到数据
        }

        // 在添加数据后，手动设置范围
        axisX->setRange(timestamps.first(), timestamps.last());

        // 计算所有数据的最小值和最大值
        double minY = std::min({
            *std::min_element(temperatures.begin(), temperatures.end()),
            *std::min_element(humidities.begin(), humidities.end()),
            *std::min_element(lights.begin(), lights.end())
        });

        double maxY = std::max({
            *std::max_element(temperatures.begin(), temperatures.end()),
            *std::max_element(humidities.begin(), humidities.end()),
            *std::max_element(lights.begin(), lights.end())
        });

        // 添加一些边距，确保数据不会紧贴坐标轴
        double margin = (maxY - minY) * 0.1;
        axisY->setRange(minY - margin, maxY + margin);

        m_chart->addSeries(tempSeries);
        m_chart->addSeries(humiditySeries);
        m_chart->addSeries(lightSeries);

        tempSeries->attachAxis(axisX);
        tempSeries->attachAxis(axisY);

        humiditySeries->attachAxis(axisX);
        humiditySeries->attachAxis(axisY);

        lightSeries->attachAxis(axisX);
        lightSeries->attachAxis(axisY);

        m_chartView->repaint();
    } else {
        // 创建柱状图
        QBarSet *tempSet = new QBarSet("温度 (°C)");
        QBarSet *humiditySet = new QBarSet("湿度 (%)");
        QBarSet *lightSet = new QBarSet("光照 (lux)");

        for (int i = 0; i < temperatures.size(); i++) {
            *tempSet << temperatures[i];
            *humiditySet << humidities[i];
            *lightSet << lights[i];
        }

        QBarSeries *series = new QBarSeries();
        series->append(tempSet);
        series->append(humiditySet);
        series->append(lightSet);

        m_chart->addSeries(series);

        QBarCategoryAxis *axis = new QBarCategoryAxis();
        QStringList categories;
        for (const auto &timestamp : timestamps) {
            categories.append(timestamp.toString("MM-dd HH:mm"));
        }
        axis->append(categories);

        m_chart->addAxis(axis, Qt::AlignBottom);
        series->attachAxis(axis);
        series->attachAxis(axisY);
    }

    m_chart->setTitle("历史数据趋势分析");
    m_chartView->repaint();
}

bool HistoryDataWidget::exportToCsv(const QString &fileName)
{
    QFile file(fileName);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        QMessageBox::warning(this, "导出失败", "无法打开文件: " + fileName);
        return false;
    }

    QTextStream out(&file);

    // 写入表头
    for (int i = 0; i < m_dataModel->columnCount(); i++) {
        out << m_dataModel->headerData(i, Qt::Horizontal).toString() << ",";
    }
    out << "\n";

    // 写入数据
    for (int i = 0; i < m_dataModel->rowCount(); i++) {
        for (int j = 0; j < m_dataModel->columnCount(); j++) {
            out << m_dataModel->data(m_dataModel->index(i, j)).toString() << ",";
        }
        out << "\n";
    }

    file.close();
    QMessageBox::information(this, "导出成功", "数据已成功导出到: " + fileName);
    m_pLog->log(m_pSqliteManage,SYSTEM_LOG,WARNING,QString("导出历史数据到：%1").arg(fileName),m_pSqliteManage->getUserIdByName(username));
    return true;
}

bool HistoryDataWidget::exportToExcel(const QString &fileName)
{
    // 使用OLE自动化导出到Excel
    QAxObject *excel = new QAxObject("Excel.Application", this);
    if (!excel) {
        QMessageBox::warning(this, "导出失败", "无法启动Excel应用程序!");
        return false;
    }

    excel->dynamicCall("SetVisible(bool)", false);
    QAxObject *workbooks = excel->querySubObject("Workbooks");
    QAxObject *workbook = workbooks->querySubObject("Add");
    QAxObject *worksheet = workbook->querySubObject("Worksheets(int)", 1);

    // 写入表头
    for (int i = 0; i < m_dataModel->columnCount(); i++) {
        QAxObject *cell = worksheet->querySubObject("Cells(int, int)", 1, i + 1);
        cell->dynamicCall("SetValue(const QVariant&)",
                          QVariant(m_dataModel->headerData(i, Qt::Horizontal).toString()));
    }

    // 写入数据
    for (int i = 0; i < m_dataModel->rowCount(); i++) {
        for (int j = 0; j < m_dataModel->columnCount(); j++) {
            QAxObject *cell = worksheet->querySubObject("Cells(int, int)", i + 2, j + 1);
            cell->dynamicCall("SetValue(const QVariant&)",
                              QVariant(m_dataModel->data(m_dataModel->index(i, j)).toString()));
        }
    }

    // 保存文件
    workbook->dynamicCall("SaveAs(const QString&)", QDir::toNativeSeparators(fileName));
    workbook->dynamicCall("Close()");
    excel->dynamicCall("Quit()");

    delete excel;

    QMessageBox::information(this, "导出成功", "数据已成功导出到: " + fileName);
    m_pLog->log(m_pSqliteManage,SYSTEM_LOG,WARNING,QString("导出历史数据到：%1").arg(fileName),m_pSqliteManage->getUserIdByName(username));
    return true;
}

void HistoryDataWidget::onExportCsvButtonClicked()
{
    QString fileName = QFileDialog::getSaveFileName(this, "导出CSV文件",
                                                     QDir::homePath(), "CSV文件 (*.csv)");
    if (!fileName.isEmpty()) {
        exportToCsv(fileName);
    }
}

void HistoryDataWidget::onExportExcelButtonClicked()
{
    QString fileName = QFileDialog::getSaveFileName(this, "导出Excel文件",
                                                     QDir::homePath(), "Excel文件 (*.xlsx)");
    if (!fileName.isEmpty()) {
        exportToExcel(fileName);
    }
}

void HistoryDataWidget::onChartTypeChanged(int index)
{
    updateChart();
}

bool HistoryDataWidget::isDuplicateQuery(int deviceId, const QDateTime &startTime, const QDateTime &endTime)
{
    QueryParams current = {deviceId, startTime, endTime};

    if (current == m_lastQuery && !m_dataModel->rowCount() == 0) {
        QMessageBox::information(this, "重复查询", "当前查询条件与上次相同，数据已加载");
        return true;
    }

    m_lastQuery = current;
    return false;
}
